<?php

/*

	Copyright © 2011 Mike Bennett <mike@kereru.com>

	This file is part of Tazu-Time.

    Tazu-Time is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    Tazu-Time is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tazu-Time.  If not, see <http://www.gnu.org/licenses/>.
    
*/


class Reports {

	var $timesheets = FALSE;		// timesheet.db
	var $customers = FALSE;			// customers.db


	// Reports
	var $reports = array();
	var $report_id='';
	var $customer_id='';
	var $task_id='';
	var $start='';
	var $end='';
	
	// Report writing strings
	var $name = '';					// Company name for reports

	var $output_file = FALSE;
	

	function __construct($timesheets=FALSE, $customers=FALSE) {

		$this->timesheets = $timesheets;
		$this->customers = $customers;
		
		$this->reports = array(
		
								1 => array(
										'code'		=>	'daily',
										'name'		=> 'Customer(s): Timesheet, all projects, sub-totals by day.',
										'customer'	=> FALSE,
										'task'		=> FALSE,
										'html'		=> TRUE,
									),
								
								2 => array(
										'code'		=>	'daily_proj',
										'name'		=> 'Project: Timesheet, selected project, sub-totals by day.',
										'customer'	=> FALSE,
										'task'		=> TRUE,
										'html'		=> TRUE,
									),
								
								3 => array(
										'code'		=>	'project_list',
										'name'		=> 'Projects: All project codes and descriptions.',
										'customer'	=> FALSE,
										'task'		=> FALSE,
										'html'		=> TRUE,
									),
								
								4 => array(
										'code'		=>	'billing',
										'name'		=> 'Billing: Hours and charging for selected period. (Without fixed charges)',
										'customer'	=> FALSE,
										'task'		=> FALSE,
										'html'		=> TRUE,
									),
								
								5 => array(
										'code'		=>	'billing_all',
										'name'		=> 'Billing: Hours and charging for selected period. (All)',
										'customer'	=> FALSE,
										'task'		=> FALSE,
										'html'		=> TRUE,
									),

								6 => array(
										'code'		=>	'timesheets_csv',
										'name'		=> 'CSV Timesheets: Timesheet data as a CSV file.',
										'customer'	=> FALSE,
										'task'		=> FALSE,
										'csv'		=> TRUE,
									),
								
								);
	


	}


	

	// Report by customer
	function report($report_id,$customer_id,$task_id,$start,$end,$output_file=FALSE) {



		$this->report_id = $report_id;
		$this->customer_id = $customer_id;
		$this->task_id = $task_id;
		$this->start = $start;
		$this->end = $end;
		if ( $output_file ) $this->output_file = $output_file;


		$result = '';

		$name = $this->reports[$report_id]['name'];
		$code = $this->reports[$report_id]['code'];



		if ( $code == 'daily' ) {
			$result .= $this->daily_cust();		
			$result .= $this->report_footer();
		}

		if ( $code == 'daily_proj' ) {
			$result .= $this->daily_proj();		
			$result .= $this->report_footer();
		}

		if ( $code == 'project_list' ) {
			$result .= $this->project_list();		
			$result .= $this->report_footer();
		}

		if ( $code == 'billing' ) {
			$result .= $this->billing(array(0));		
			$result .= $this->report_footer();
		}

		if ( $code == 'billing_all' ) {
			$result .= $this->billing(array(0,1,2));		
			$result .= $this->report_footer();
		}

		if ( $code == 'timesheets_csv' ) {
			$result .= $this->timesheets_csv();		
		}



//array_dump( $this->reports[$report_id] );		
//wb_message_box(null,$report['name']);

//		file_put_contents('report.htm',$result);

		return( $result );
	
	}

	function daily_cust() {
	
		$result = '';
		
		$result .= $this->report_header();

	
		if ( $this->customer_id ) {
			$qry = sprintf("SELECT * FROM entries WHERE customer_id='%s' and deleted=0 and start>='%s' and start<='%s' order by start;",$this->customer_id,date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));
		}
		else {
			$qry = sprintf("SELECT * FROM entries WHERE deleted=0 and start>='%s' and start<='%s' order by start;",date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));
		}
	
		$result .= $this->daily($qry);

		return( $result );

	}




	function daily_proj() {

		$cs = new Customers($this->customers);
	
		$result = '';

		// Report heading

		$heading = '';

		// Customer
		$name = $cs->getCustomerName($this->customer_id);
		$company = $cs->getCustomerCompany($this->customer_id);
		$heading .= sprintf("<u><b>%s</b>   (%s)</u>",$company, $name);


		// Task
		$name_proj = $cs->getProjectDescription($this->task_id);
		$code_proj = $cs->getProjectCode($this->task_id);
		
		
		$heading .= sprintf("<br><u><b>%s</b>  (%s)</u>",$name_proj,$code_proj);
		$heading .= sprintf("<br><b>%s</b>", $this->reports[$this->report_id]['name'] );
		$heading .= sprintf("<br>%s - %s",$this->day($this->start),$this->day($this->end));
		
		
		$result .= $this->report_header($heading);
	
		$qry = sprintf("SELECT * FROM entries WHERE deleted=0 and task_id='%s' and start>='%s' and start<='%s' order by start;",$this->task_id,date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));

//wb_message_box(null,$qry);

		$result .= $this->daily($qry);

		return( $result );


	}

	function project_list() {
	
//		$ts = new Timesheet($this->timesheets,$this->customers);
		$cs = new Customers($this->customers);

//echo "[$this->customers]\n";

		$result = '';
		$result .= $this->report_header();

		if ( $this->customer_id ) {
			$qry = sprintf("SELECT * FROM tasks WHERE customer_id='%s' order by customer_id, task_code;",$this->customer_id);
		}
		else {
			$qry = sprintf("SELECT * FROM tasks order by customer_id,task_code;");
		}


		$rows = $cs->rows($qry,array('id','task_code','customer_id','task','charged','rate','period'));

		$last_customer='';


		foreach ( $rows as $i => $dat ) {

			$cust_name = $cs->getCustomerName($dat['customer_id']);
			$cust_company = $cs->getCustomerCompany($dat['customer_id']);
			$cust_email_bill = trim($cs->col($dat['customer_id'],'customers','email'));

			$cur_customer = $dat['customer_id'];

			// Change of customer 
			if ( $cur_customer <> $last_customer ) {
			
				if ( $cust_name ) {
					
					$txt = $cust_name.' - '.$cust_company;
					if ( $cust_email_bill <> '' ) {
						$txt .= ' - '.$cust_email_bill;
					}
				}
				else {
					$txt = settings::xlate('UNKNOWN [customer]: '.$cur_customer);
				}				
			
				$result .= $this->report_line('full_line_left','<b>'.$txt.'</b>');
			}
			
			
			if ( $dat['charged'] ) {
			
				$period = '/period';
				if ( $dat['period'] == 0 ) $period = '/hour';
				if ( $dat['period'] == 2 ) $period = ' quote';
			
				$rate = sprintf("<div style=\"text-align: right; border: 1px solid black; padding: 2px;\">%s</div>",sprintf("%01.2f %s",$dat['rate'],$period));
			}
			else {
				$rate = '';
			}
			
			$result .= $this->report_line(FALSE,"<div style=\"width: 50px;\">&nbsp;</div>",$dat['task_code'],$dat['task'],$rate);

			$last_customer = $cur_customer;
		}

		return( $result );

	}

	function timesheets_csv() {
	
	
		if ( $this->customer_id ) {
			$qry = sprintf("SELECT * FROM entries WHERE customer_id='%s' and deleted=0 and start>='%s' and start<='%s' order by start;",$this->customer_id,date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));
		}
		else {
			$qry = sprintf("SELECT * FROM entries WHERE deleted=0 and start>='%s' and start<='%s' order by start;",date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));
		}
	
		return($this->entries_csv($qry));

	}

	function entries_csv($qry) {

		$ts = new Timesheet($this->timesheets,$this->customers);
		$cs = new Customers($this->customers);

	    if (!$handle = fopen($this->output_file, 'w')) {
			platform::error_popup('Unable to open <b>'.$this->output_file.'</b> for writing.','Tazu-Timesheet - Error'); 
			return(FALSE);
	    }

	
		// Attached data types
		$c = new settings(platform::app_data('Tazu-Timesheet').'config.db');
		$data_types = $c->getDataTypes();
		unset($c);

		$rows = $ts->rows($qry,array('id','start','elapsed','comment','task_id'));

		// Column headings
		$line = "\"Entry Id\",\"Project ID\",\"Customer ID\",\"Customer\",\"Project\",\"Project desc\",\"Date\",\"Time\",\"Elapsed\",\"Comment\",\"Charged\"";
		$line2 = "\"entry_id\",\"project_id\",\"customer_id\",\"cust_code\",\"project_code\",\"project_desc\",\"date\",\"time\",\"hours\",\"comment\",\"charged\"";

		if ( is_array( $data_types ) ) {
			foreach ( $data_types as $idx => $dat1 ) {
					$id = $dat1['id'];
					$tag = $dat1['tag'];
					$name = $dat1['name'];
					$type = $dat1['type'];
					$unit = $dat1['unit'];
					$description = $dat1['description'];

					$line .= sprintf(",\"%s %s%s%s\"",$name,($unit<>'')?'(':'',$unit,($unit<>'')?')':'');
					$line2 .= sprintf(",\"%s\"",$tag);
			}
		}

		if (fwrite($handle, "$line\n") === FALSE) {
			@fclose($handle);
			platform::error_popup('Unable to write to <b>'.$this->output_file.'</b> for writing.','Tazu-Timesheet - Error'); 
			return(FALSE);
		}

		if (fwrite($handle, "$line2\n") === FALSE) {
			@fclose($handle);
			platform::error_popup('Unable to write to <b>'.$this->output_file.'</b> for writing.','Tazu-Timesheet - Error'); 
			return(FALSE);
		}


		foreach ( $rows as $i => $dat ) {

//print_r($dat);

			// Entry
			$start = explode(' ',$dat['start']);
			$start_date = $start[0];			
			$start_time = $start[1];			

			$elapsed_secs = $dat['elapsed'];
			$elapsed_hours = $this->elapsed_decimal($dat['elapsed']);
			$comment = $dat['comment'];

			// Is this a charged entry ?
			$task_id = $dat['task_id'];
			$charged = ($cs->getProjectField($task_id,'charged') == 1);

			// Project
			$name_proj = $cs->getProjectDescription($task_id);
			$code_proj = $cs->getProjectCode($task_id);
			$customer_id = $cs->getProjectCustId($task_id);

			// Customer
			$cust_name = $cs->getCustomerName($customer_id);			

			// attached data
			$data = $ts->getData($dat['id']);			

//print_r($data);

			$line = sprintf('"%s","%s","%s","%s","%s","%s","%s","%s","%s","%s","%s"',
							$dat['id'],
							$task_id,
							$customer_id,
							$cust_name,
							$code_proj,
							$name_proj,
							$start_date,
							$start_time,
							$elapsed_hours,
							addslashes($comment),
							($charged)?'Y':'N'
							);


			// Add any attached data
			if ( is_array( $data_types ) ) {
				foreach ( $data_types as $idx => $dat1 ) {
					$id = $dat1['id'];
					$tag = $dat1['tag'];
					$name = $dat1['name'];
					$type = $dat1['type'];
					$unit = $dat1['unit'];
					$description = $dat1['description'];

					$cell = '';
					foreach ( $data as $idx2 => $dat2 ) {
	
						if ( $dat2['type'] == $id ) {
							// This entry has some attached dat of this type
							$cell .= $dat2['value']."\n";							
						}
					}				
					$cell = sprintf(",\"%s\"",trim($cell));
					$line .= $cell;
				}
			}
			

			if (fwrite($handle, "$line\n") === FALSE) {
				@fclose($handle);
				platform::error_popup('Unable to write to <b>'.$this->output_file.'</b> for writing.','Tazu-Timesheet - Error'); 
				return(FALSE);
			}


//echo "$line\n";


		}


		@fclose($handle);
		
		return(TRUE);



	}



	function billing($types=array(0,1,2,3,4,5,6,7,8)) {

		$ts = new Timesheet($this->timesheets,$this->customers);
		$cs = new Customers($this->customers);

		// $types = list of charging period codes to put on the report

	
		$result = '';
		$result .= $this->report_header();

		// Column headings
		$result .= $this->report_line(
										'col_heading',
										'',
										'',
										'Task',
										'<div style="text-align:right;">Hours</div>',
										'<div style="text-align:right;">Rate</div>',
										'<div style="text-align:right;">Billed</div>'
									);


		if ( $this->customer_id ) {
			$qry = sprintf("SELECT * FROM customers WHERE id='%s' order by name;",$this->customer_id);
		}
		else {
			$qry = sprintf("SELECT * FROM customers order by name;");
		}


		$rows = $cs->rows($qry,array('id','company','name','email'));

		$last_customer='';

		// Customer totals
		$total_elapsed = 0;		// hours
		$total_charged = 0;		// hours
		$total_billed = 0;		// money

		$g_total_elapsed = 0;		// hours
		$g_total_charged = 0;		// hours
		$g_total_billed = 0;		// money


		foreach ( $rows as $i => $dat ) {

			$cust_name = $dat['name'];
			$cust_company = $dat['company'];
			$cust_email_bill = trim($dat['email']);

			$cur_customer = $dat['id'];


			// Change of customer 
			if ( $cur_customer <> $last_customer ) {
			
			
				if ( $last_customer <> '' ) {
				
					// Previous customer total
					$result_customer .= $this->report_line(
														FALSE,
														'',
														'',
														sprintf("<div style=\"text-align:right;color:#AFAFAF;\">%s</div>",'Charged/Worked'),
														sprintf("<div style=\"text-align:right;font-weight:normal;border:1px solid black;padding:4px;\">%01.2f/%01.2f</div>",$this->elapsed_decimal($total_charged),$this->elapsed_decimal($total_elapsed)),
														'',
														sprintf("<div style=\"text-align:right;font-weight:bold;border:1px solid black;padding:4px;\">%01.2f</div>",$total_billed)
													);

					$result_customer .= $this->report_vertical_space(25);
					
					
					// Add this customer to the overall report
					if ( $total_billed*1 > 0 ) {
						$result .= $result_customer;
					}
					
					// Reset totals
					$total_elapsed = 0;		// hours
					$total_charged = 0;		// hours
					$total_billed = 0;		// money

					$result_customer = '';

				}
			
				$txt = $cust_name.' - '.$cust_company;
				if ( $cust_email_bill <> '' ) {
					$txt .= '<br>'.$cust_email_bill;
				}
			
				$result_customer .= $this->report_line('full_line_left','<b>'.$txt.'</b>');
			}

			
			// All of the fixed period charges
			$qry = sprintf("SELECT * FROM tasks WHERE customer_id='%s' order by charged,period;",$cur_customer);
			$rows1 = $cs->rows($qry,array('id','task_code','task','rate','charged','period','bill_date'));

			foreach ( $rows1 as $i1 => $dat1 ) {
				$task_code = $dat1['task_code'];
				$task = $dat1['task'];
				$rate = $dat1['rate'];
				$charged = $dat1['charged'];
				$period = $dat1['period'];
				$bill_date = $dat1['bill_date'];


				if ( in_array($period, $types) ) {

					$task_id = $dat1['id'];
		
					$qry = sprintf("SELECT * FROM entries WHERE deleted=0 and task_id='%s' and  start>='%s' and start<='%s' order by start;",$task_id,date("Y-m-d 00:00:00",$this->start),date("Y-m-d 23:59:59",$this->end));
					$rows2 = $ts->rows($qry,array('id','elapsed'));
					$task_elapsed=0;
					if ( is_array( $rows2 ) ) {
						foreach ( $rows2 as $i2 => $dat2 ) {
							$task_elapsed += $dat2['elapsed']; 
						}
					}
						
					$total_elapsed += $task_elapsed;
					$g_total_elapsed += $task_elapsed;
	
					if ( $period == 0 ) {			// hourly
	
	
						$task_charge = $this->elapsed_decimal($task_elapsed) * $rate;				
	
						$show_line = TRUE;
						
						if ( $charged ) {
								$total_billed += $task_charge;
								$g_total_billed += $task_charge;
								$t_elapsed = sprintf("<div style=\"text-align:right;\">%s</div>",$this->elapsed_decimal($task_elapsed));
								$t_rate = sprintf("<div style=\"text-align:right;\">%01.2f</div>",$rate);
								$t_bill = sprintf("<div style=\"text-align:right;font-weight:bold;\">%01.2f</div>",$task_charge);
			
								$total_charged += $task_elapsed;
								$g_total_charged += $task_elapsed;
	
								if ( $task_charge <=0 ) $show_line=FALSE;		// Don't show zero hour lines
	
						}
						else {
						
								$t_elapsed = sprintf("<div style=\"text-align:right;\">%s</div>",$this->elapsed_decimal($task_elapsed));
								$t_rate = '';
								$t_bill = '';

								if ( $task_elapsed*1 <=0 ) $show_line=FALSE;		// Don't show zero hour lines
						}
	
						if ( $show_line ) {
						
							$result_customer .= $this->report_line(
															FALSE,
															'<div style="text-align:right;color:#AFAFAF;">Time</div>',
															$dat1['task_code'],
															$dat1['task'],
															$t_elapsed,
															$t_rate,
															$t_bill
														);
						}
					}
	
					if ( $period == 1 ) {			// billing period
	
						if ( $charged ) {
								$total_billed += $rate;
								$g_total_billed += $rate;
								$t_elapsed = sprintf("<div style=\"text-align:right;\">%s</div>",$this->elapsed_decimal($task_elapsed));
								$t_rate = '';
								$t_bill = sprintf("<div style=\"text-align:right;font-weight:bold;\">%01.2f</div>",$rate);
			
						}
						else {
								$t_elapsed = '';
								$t_rate = '';
								$t_bill = '';
						}
	

						
							$result_customer .= $this->report_line(
															FALSE,
															'<div style="text-align:right;color:#AFAFAF;">Fixed</div>',
															$dat1['task_code'],
															$dat1['task'],
															$t_elapsed,
															$t_rate,
															$t_bill
														);

					}


					if ( $period == 2 ) {			// quote

						// $period = 2 is a quote. Only report if the bill_date falls within reporting period
						if ( $bill_date >= $this->start && $bill_date <= $this->end ) { 	
							if ( $charged ) {
									$total_billed += $rate;
									$g_total_billed += $rate;
									$t_elapsed = sprintf("<div style=\"text-align:right;\">%s</div>",$this->elapsed_decimal($task_elapsed));
									$t_rate = '';
									$t_bill = sprintf("<div style=\"text-align:right;font-weight:bold;\">%01.2f</div>",$rate);
				
							}
							else {
									$t_elapsed = '';
									$t_rate = '';
									$t_bill = '';
							}
		
								$result_customer .= $this->report_line(
																FALSE,
																'<div style="text-align:right;color:#AFAFAF;">Quote</div>',
																$dat1['task_code'],
																$dat1['task'],
																$t_elapsed,
																$t_rate,
																$t_bill
															);
						
						}
					}

				}	

			}


			


			$last_customer = $cur_customer;
		}

		// Last customer totals
					$result_customer .= $this->report_line(
														FALSE,
														'',
														'',
														sprintf("<div style=\"text-align:right;color:#AFAFAF;\">%s</div>",'Charged/Worked'),
														sprintf("<div style=\"text-align:right;font-weight:normal;border:1px solid black;padding:4px;\">%01.2f/%01.2f</div>",$this->elapsed_decimal($total_charged),$this->elapsed_decimal($total_elapsed)),
														'',
														sprintf("<div style=\"text-align:right;font-weight:bold;border:1px solid black;padding:4px;\">%01.2f</div>",$total_billed)
													);

					$result_customer .= $this->report_vertical_space(25);



		// Grand totals
		$result .= $this->report_line(
													FALSE,
														'TOTALS',
														'',
														sprintf("<div style=\"text-align:right;color:#AFAFAF;\">%s</div>",'Charged/Worked'),
														sprintf("<div style=\"text-align:right;font-weight:normal;border:3px double black;padding:4px;\">%01.2f/%01.2f</div>",$this->elapsed_decimal($g_total_charged),$this->elapsed_decimal($g_total_elapsed)),
														'',
														sprintf("<div style=\"text-align:right;font-weight:bold;border:3px double black;padding:4px;\">%01.2f</div>",$g_total_billed)
													);

					$result .= $this->report_vertical_space(25);

		return( $result );

	}




	// Standard report line of 10 cols
	function report_line($type=FALSE,$col1='',$col2='',$col3='',$col4='',$col5='',$col6='',$col7='',$col8='',$col9='',$col10='') {

		/* All report bodies have 10 columns
		 8 = elapsed (decimal)
		*/		


		if ( $type == 'col_heading' ) {
			$fmt = "
			<tr>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			</tr>";
		}
		elseif ( $type == 'full_width_left' ) {
			$fmt = "
			<tr>
			 <td colspan=\"10\" style=\"font-weight: bold;\">%s</td>
			 <td>%s%s%s%s%s%s%s%s%s</td>
			</tr>";
		}
		else {
			$fmt = "
			<tr>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			</tr>";
		}		


		$result = sprintf($fmt,
							$col1,
							$col2,
							$col3,
							$col4,
							$col5,
							$col6,
							$col7,
							$col8,
							$col9,
							$col10
					);

//		if ( $heading ) $result .= $this->report_hr();

		return( $result );
	}





	function daily($qry) {
	
		$ts = new Timesheet($this->timesheets,$this->customers);
		$cs = new Customers($this->customers);

		$result = '';

		$rows = $ts->rows($qry,array('id','start','elapsed','comment','task_id'));

		$day_ttl=0;
		$chg_ttl=0;
		$grand_ttl=0;
		$chg_grand_ttl=0;
		$last_day='';

		// Column headings
		$result .= $this->report_entry(TRUE,'Project','Time','Notes','HH:MM<br>(Worked)','HH:MM<br>(Charged)','HH');

				
		// Massage for display
		foreach ( $rows as $i => $dat ) {

			// Is this a charged entry ?
			$task_id = $dat['task_id'];
			$charged = ($cs->getProjectField($task_id,'charged') == 1 && $cs->getProjectField($task_id,'period') <> 2);

			$period = $cs->getProjectField($task_id,'period');
//			$bill_date = $cs->getProjectField($task_id,'bill_date');


			$cur_day = substr($dat['start'],0,10);
			if ( $last_day == '' ) $last_day = $cur_day;


			// Change of day - totals line
			if ( $cur_day <> $last_day ) {
				// Daily total	
				$result .= $this->report_day_total($this->day($this->timestamp2unix($last_day)).'  Total',$day_ttl,$chg_ttl);
				$result .= $this->report_vertical_space(15);


				// reset total
				$day_ttl = 0;
				$chg_ttl = 0;

			}
			
//wb_message_box(null,$dat['task_code']);

			$day_ttl = $day_ttl + $dat['elapsed'];
			if ( $charged ) $chg_ttl = $chg_ttl + $dat['elapsed'];

			$grand_ttl = $grand_ttl + $dat['elapsed'];
			if ( $charged ) $chg_grand_ttl = $chg_grand_ttl + $dat['elapsed'];

			$elapsed = $dat['elapsed'];
			$chg_elapsed = 0;
			if ( $charged ) {
					$chg_elapsed = $elapsed;
			}
			
			$result .= $this->report_entry(FALSE,$cs->getProjectCode($dat['task_id']),$this->day_time($this->timestamp2unix($dat['start'])),$dat['comment'],$this->elapsed($elapsed),$this->elapsed($chg_elapsed),$this->elapsed_decimal($chg_elapsed));

			$last_day = $cur_day;
		}

		// Last Daily total	
		$result .= $this->report_day_total($this->day($this->timestamp2unix($last_day)).'  Total',$day_ttl,$chg_ttl);
		$result .= $this->report_vertical_space(15);


		// Grand total	
		$result .= $this->report_period_total('Total for Period',$grand_ttl,$chg_grand_ttl);

		return( $result );

	}


	function report_vertical_space($px) {
		return( sprintf("<tr><td style=\"height: %spx;\"></td></tr>",$px));
	}

	// 1 line of standard timesheet entry
	function report_entry($heading=FALSE,$task_code,$start_timestamp,$comment,$elapsed,$chg_elapsed,$elapsed_decimal) {

		/* All report bodies have 10 columns
		 1 = unused
		 2 = unused
		 3 = unused
		 4 = task code
		 5 = start time
		 6 = comment
		 7 = elapsed (mins)
		 8 = elapsed (decimal)
		*/		


		if ( $heading ) {
			$fmt = "
			<tr>
			 <td></td>
			 <td></td>
			 <td></td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold;\">%s</td>
			 <td style=\"font-weight: bold; text-align: right;\">%s</td>
			 <td style=\"font-weight: bold; text-align: right;\">%s</td>
			 <td style=\"font-weight: bold; text-align: right;\">%s</td>
			 <td></td>
			 <td></td>
			</tr>";
		}
		else {
			$fmt = "
			<tr>
			 <td></td>
			 <td></td>
			 <td></td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top;\">%s</td>
			 <td style=\"vertical-align: top; text-align: right;\">%s</td>
			 <td style=\"vertical-align: top; text-align: right;\">%s</td>
			 <td style=\"vertical-align: top; text-align: right;\">%s</td>
			 <td></td>
			 <td></td>
			</tr>";
		}		


		$result = sprintf($fmt,
							$task_code,
							$start_timestamp,
							nl2br($comment),
							$elapsed,
							$chg_elapsed,
							$elapsed_decimal
					);

		if ( $heading ) $result .= $this->report_hr();

		return( $result );
	}


	function report_day_total($label,$elapsed,$chg_elapsed) {
		/* All report bodies have 10 columns
		 1 = unused
		 2 = unused
		 3 = unused
		 4 = unused
		 5 = label
		 6 = elapsed (mins)
		 7 = elapsed (decimal)
		*/		

		$result = sprintf("
		<tr>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td></td>
		</tr>",
		
		$label,
		$this->elapsed($elapsed),
		$this->elapsed($chg_elapsed),
		$this->elapsed_decimal($chg_elapsed)
		);

		return( $result );
	}

	function report_period_total($label,$elapsed,$chg_elapsed) {

		/* All report bodies have 10 columns
		 1 = unused
		 2 = unused
		 3 = unused
		 4 = unused
		 5 = label
		 6 = elapsed (mins)
		 7 = charged_elapsed (mins)
		 8 = charged_elapsed (decimal)
		*/		

		$result = sprintf("
		<tr>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td></td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; text-align: right; font-weight: bold;\">%s</td>
		 <td></td>
		</tr>",
		
		$label,
		$this->elapsed($elapsed),
		$this->elapsed($chg_elapsed),
		$this->elapsed_decimal($chg_elapsed)
		);

		return( $result );
	}


	function report_hr() {
		return("<tr><td colspan=\"10\"><div style=\"border-bottom: 1px solid black; height: 4px;\"></td></tr>");			
	}

	function report_header($heading=FALSE) {
	
//		$ts = new Timesheet($this->timesheets,$this->customers);
		$cs = new Customers($this->customers);

		$result = '';
		$result .= "<table width=\"100%\"cellspacing=\"0\" cellpadding=\"5\" style=\"font-family: helvetica,sans,sans-serif;\">";

		if ( $this->name <> '' ) {
			$result .= "<tr><td colspan=\"10\"><div style=\"border: 1px solid black; padding: 5px; background-color: #ECECEC;\">";
			$result .= "<center><b>".$this->name."</b></center>";
			$result .= "</td></tr>";
		}
		
		$result .= "<tr><td colspan=\"10\"><div style=\"border: 1px solid black; padding: 5px; background-color: #ECECEC;\">";

		if ( $heading ) {
			$result .= $heading;
		}
		else {
		
			// Default heading
					
			if ( $this->customer_id ) {
				$name = $cs->getCustomerName($this->customer_id);
				$company = $cs->getCustomerCompany($this->customer_id);
				$result .= sprintf("<u><b>%s</b>   (%s)</u>",$company, $name);
			}
			else {
				$result .= sprintf("<b>%s</b>", 'All Customers' );
			}
			
			$result .= sprintf("<br><b>%s</b>", $this->reports[$this->report_id]['name'] );
			
			$result .= sprintf("<br>%s - %s",$this->day($this->start),$this->day($this->end));
	
		}

		$result .= "</div></td></tr>";

		return( $result );	
	}
	
	
	
	function report_footer() {
	
		$result = '';
		$result .= "<tr><td colspan=\"10\"><div style=\"margin-top: 10px; border: 1px solid black; padding: 5px; background-color: #ECECEC;\">";
		$result .= "Timesheets Program By : Pikaia Ltd.  <a href=\"http://pikaia.co.nz\" target=\"_blank\">http://pikaia.co.nz</a>";		
		$result .= "</div></td></tr>";
		$result .= "</table>";
	
		return( $result );
	}

	// Return list of reports for a listbox
	function getReports() {
		$result = array();
		foreach ( $this->reports as $id => $dat ) {
			$result[$id] = $dat['name'];
		}	

		return( $result);
	}


	// Input unix time to displayed day and time
	function day($u) {
		return( @ date("D d M Y",$u) );
	}

	// Input unix time to displayed day and time
	function day_time($u) {
		return( @ date("D d M Y H:i",$u) );
	}


	// Format total seconds for display
	function elapsed($secs) {

		$secs = $this->rnd_secs($secs);

		$hours = floor( $secs / 3600 );
		$secs = fmod( $secs , 3600 );
		

		$mins = floor( $secs / 60);
		
		$result = sprintf("%02d:%02d", $hours, $mins);
		
		return( $result );
	
	}

	// Format total seconds for display
	function elapsed_decimal($secs) {

		$secs = $this->round_secs_2_decimal($secs);

		$hours = $secs / 3600;
		
// Request from Bruce. 2 decimal places
//		$result = sprintf("%0.1f", $hours);
		$result = sprintf("%0.2f", $hours);
		
		return( $result );
	
	}


	function rnd_secs($secs) {

		$hours = floor( $secs / 3600 );
		$secs = fmod( ($secs*1) , 3600 );
		

		$mins = floor( $secs / 60);
		
		$secs = fmod( $secs , 60 );
		if ( $secs > 0 ) $mins++;			// Round up to nearest minute
		
		$result = ($hours*3600) + ($mins*60);

		return( $result );
	
	}




	// Round up to 6 min intervals (0.1 hour)
	function round_secs_2_decimal($secs) {
	
		$secs = $this->rnd_secs($secs);

// Request from Bruce. Don't do this
return( $secs );

		$hours = floor( $secs / 3600 );
		$secs = fmod( $secs , 3600 );
		$mins = floor( $secs / 60);
		

		if ( $mins <=6 && $mins > 0 ) $mins = 6;
		elseif ( $mins <=12 && $mins > 6 ) $mins = 12;
		elseif ( $mins <=18 && $mins > 12 ) $mins = 18;
		elseif ( $mins <=24 && $mins > 18 ) $mins = 24;
		elseif ( $mins <=30 && $mins > 24 ) $mins = 30;
		elseif ( $mins <=36 && $mins > 30 ) $mins = 36;
		elseif ( $mins <=42 && $mins > 36 ) $mins = 42;
		elseif ( $mins <=48 && $mins > 42 ) $mins = 48;
		elseif ( $mins <=54 && $mins > 48 ) $mins = 54;
		elseif ( $mins <=60 && $mins > 54 ) $mins = 60;
		
		
		$result = ($hours*3600) + ($mins*60);

		return( $result );
	
	}


	function timestamp2unix($timestamp) {
		$y = substr($timestamp,0,4);
		$m = substr($timestamp,5,2);
		$d = substr($timestamp,8,2);
		$h = substr($timestamp,11,2);
		$i = substr($timestamp,14,2);
		$s = substr($timestamp,17,2);
		
		$u = mktime($h,$i,$s,$m,$d,$y);
		return( $u );
	}

	// Input unix time to displayed day and time
	function unix2timestamp($u) {
		return( @ date("Y-m-d H:i:s",$u) );
	}




}



?>